package model.strategys;

import java.util.ArrayList;
import java.util.Collection;

import model.cubos.Adesivo;
import model.cubos.Cor;
import model.cubos.CuboMagico;
import model.cubos.CuboMagico3x3x3;
import model.rotations.RotationsImpl;
import view.MainAuxiliar;

/**
 * @author
 *         Classe que contém o algoritmo básico de resolução do cubo
 */
public class AlgoritmoBasico implements MyStrategys
{

    private CuboMagico3x3x3 cubo;
    private int passo;
    private Collection movs = new ArrayList();
    private String mensagem = "";
    private Adesivo origem;
    private Adesivo destino;
    private Adesivo origemDois;
    private Adesivo destinoDois;
    private final RotationsImpl rotacao = new RotationsImpl();

    public AlgoritmoBasico()
    {
    }

    @Override
    public void resolver(CuboMagico cubo)
    {
	setCubo((CuboMagico3x3x3) cubo);
	resolveMeioSuperior();
    }

    /**
     * Método que retorna os movimentos necessários para resolução da etapa Cruz Branca do
     * Cubo à partir de uma configuração recebida juntamente com a explicação necessária
     */
    public void resolveCruz()
    {
	movs.clear();

	String aux = "";
	int i = 0;

	Adesivo[][][] matriz = cubo.getCubo();
	int flag = 0;

	/*
	 * posicionar o amarelo na face superior
	 */

	setDestino(matriz[4][1][1]);
	while (!matriz[4][1][1].isCor(Cor.AMARELO))
	{
	    if (matriz[1][1][1].isCor(Cor.AMARELO) || matriz[5][1][1].isCor(Cor.AMARELO)
		    || matriz[3][1][1].isCor(Cor.AMARELO))
	    {
		rotacao.Z(cubo);
	    }
	    if (matriz[0][1][1].isCor(Cor.AMARELO) || matriz[2][1][1].isCor(Cor.AMARELO))
	    {
		rotacao.X(cubo);
	    }
	}

	setDestino(matriz[0][1][1]);
	while (!matriz[0][1][1].isCor(Cor.AZUL))
	{// enquanto não houver quadrado branco na posi��o [0][0][1]
	    rotacao.Y(cubo);
	}

	if (matriz[0][2][1].isCor(Cor.AZUL)
		&& matriz[0][1][1].isCor(Cor.AZUL)
		&& matriz[5][0][1].isCor(Cor.BRANCO)
		&& matriz[5][1][1].isCor(Cor.BRANCO)
		&& (matriz[1][2][1].isCor(Cor.VERMELHO) && matriz[1][1][1].isCor(Cor.VERMELHO)
			&& matriz[5][1][2].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO))
		&& (matriz[2][2][1].isCor(Cor.VERDE) && matriz[2][1][1].isCor(Cor.VERDE)
			&& matriz[5][2][1].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO))
		&& (matriz[3][2][1].isCor(Cor.LARANJA) && matriz[3][1][1].isCor(Cor.LARANJA)
			&& matriz[5][1][0].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO)))
	{
	    return;
	}

	// não estiver pronto
	while (flag != 1)
	{// testar se passo está completo - 1 e 2
	    // etapa 3
	    if (matriz[0][0][1].isCor(Cor.BRANCO)
		    || // se existir branco em uma dessas posições
		    matriz[1][0][1].isCor(Cor.BRANCO) || matriz[2][0][1].isCor(Cor.BRANCO)
		    || matriz[3][0][1].isCor(Cor.BRANCO))
	    {

		aux = new String();
		mensagem = new String();
		setDestino(matriz[0][0][1]);

		while (!matriz[0][0][1].isCor(Cor.BRANCO))
		{// enquanto não houver quadrado branco na posi��o [0][0][1]
		    rotacao.U(cubo);
		}

		setDestino(matriz[0][1][2]);

		rotacao.F(cubo);

		setDestino(matriz[4][1][2]);

		while (matriz[4][1][2].isCor(Cor.BRANCO))
		{// enquanto existir quadrado branco na posi��o [4][1][2]
		    rotacao.U(cubo);// movimento U
		}

		setDestino(matriz[4][1][2]);

		rotacao.R(cubo);// movimento R
	    }
	    // fim da etapa 3
	    // ***************
	    // etapa 4
	    else // se não existir quadrado branco em nenhuma das posições [0][0][1], [1][0][1], [2][0][1], [3][0][1]
	    if (matriz[0][1][0].isCor(Cor.BRANCO)
		    || // verificar se existe quadrado branco nessas posições
		    matriz[1][1][0].isCor(Cor.BRANCO) || matriz[2][1][0].isCor(Cor.BRANCO)
		    || matriz[3][1][0].isCor(Cor.BRANCO))
	    {
		setDestino(matriz[0][1][0]);

		while (!matriz[0][1][0].isCor(Cor.BRANCO))
		{// enquanto não existir quadrado branco nessas posições
		    rotacao.Y(cubo);// movimento Y
		}

		setDestino(matriz[4][1][0]);

		while (matriz[4][1][0].isCor(Cor.BRANCO))
		{// enquanto existir quadrado branco nessas posições
		    rotacao.U(cubo);// movimento U
		}

		setDestino(matriz[4][1][0]);

		rotacao.L_(cubo);// movimento L'
	    }
	    // fim da ETAPA 4
	    // **********************
	    // etapa 5
	    else if (matriz[0][1][2].isCor(Cor.BRANCO)
		    || // verificar se existe quadrado branco nessas posições
		    matriz[1][1][2].isCor(Cor.BRANCO) || matriz[2][1][2].isCor(Cor.BRANCO)
		    || matriz[3][1][2].isCor(Cor.BRANCO))
	    {

		setDestino(matriz[3][1][2]);

		while (!matriz[3][1][2].isCor(Cor.BRANCO))
		{// enquanto não existir quadrados brancos nessas posições
		    rotacao.Y(cubo);// movimento Y
		}

		if (matriz[4][2][1].isCor(Cor.BRANCO))
		{// verificar se existe quadrado branco nessas posições

		    setDestino(matriz[4][2][1]);

		    while (matriz[4][2][1].isCor(Cor.BRANCO))
		    {// enquanto existir quadrado branco nessas posições
			rotacao.U(cubo);// movimento U
		    }
		}
		setDestino(matriz[4][2][1]);

		rotacao.F(cubo);// movimento F
	    }

	    // fim da etapa 5
	    // ********************
	    // etapa 7
	    else if (matriz[5][0][1].isCor(Cor.BRANCO)
		    || // verificar se existe quadrado branco nessas posições
		    matriz[5][1][0].isCor(Cor.BRANCO) || matriz[5][1][2].isCor(Cor.BRANCO)
		    || matriz[5][2][1].isCor(Cor.BRANCO))
	    {

		setDestino(matriz[5][0][1]);

		while (!matriz[5][0][1].isCor(Cor.BRANCO))
		{
		    rotacao.D(cubo);// movimento D
		}

		if (matriz[4][2][1].isCor(Cor.BRANCO))
		{// verificar se existe quadrado branco nessas posições

		    setDestino(matriz[4][2][1]);

		    while (matriz[4][2][1].isCor(Cor.BRANCO))
		    {// enquanto existir quadrado branco nessas posições
			rotacao.U(cubo);// movimento U
		    }

		}

		setDestino(matriz[4][2][1]);

		// realizar movimento F2
		rotacao.F(cubo);// movimento F
		rotacao.F(cubo);// movimento F

		// fim do movimento F2

	    }
	    // fim da etapa 7
	    // *********************
	    // etapa 8
	    else if (matriz[0][2][1].isCor(Cor.BRANCO)
		    || // verificar se existe quadrado branco nessas posições
		    matriz[1][2][1].isCor(Cor.BRANCO) || matriz[2][2][1].isCor(Cor.BRANCO)
		    || matriz[3][2][1].isCor(Cor.BRANCO))
	    {
		setDestino(matriz[0][2][1]);

		while (!matriz[0][2][1].isCor(Cor.BRANCO))
		{
		    rotacao.D(cubo);// movimento D
		}

		setDestino(matriz[4][2][1]);

		while (matriz[4][2][1].isCor(Cor.BRANCO))
		{
		    rotacao.U(cubo);// movimento U
		}

		rotacao.F(cubo);// movimento F
	    }
	    // fim da etapa 8
	    // *************
	    // etapa 9
	    if ((matriz[4][0][1].isCor(Cor.BRANCO))
		    && // verificar se existe quadrado branco nessas posições
		    (matriz[4][1][0].isCor(Cor.BRANCO)) && (matriz[4][1][2].isCor(Cor.BRANCO))
		    && (matriz[4][2][1].isCor(Cor.BRANCO)))
	    {

		for (int j = 0; j < 4; j++)
		{
		    setDestino(matriz[0][1][1]);

		    switch (matriz[0][1][1].getKey())
		    {
			case 4:
			    while (!(matriz[0][0][1].isCor(Cor.AZUL) && matriz[4][2][1].isCor(Cor.BRANCO)))
			    {
				rotacao.U(cubo);// movimento U
			    }
			    // realizar movimento F2

			    rotacao.F(cubo);// movimento F
			    rotacao.F(cubo);// movimento F
			    break;

			case 13:
			    while (!(matriz[0][0][1].isCor(Cor.VERMELHO) && matriz[4][2][1].isCor(Cor.BRANCO)))
			    {
				rotacao.U(cubo);// movimento U
			    }

			    // realizar movimento F2

			    rotacao.F(cubo);// movimento F
			    rotacao.F(cubo);// movimento F
			    break;

			case 22:
			    while (!(matriz[0][0][1].isCor(Cor.VERDE) && matriz[4][2][1].isCor(Cor.BRANCO)))
			    {
				rotacao.U(cubo);// movimento U
			    }
			    // realizar movimento F2

			    rotacao.F(cubo);// movimento F
			    rotacao.F(cubo);// movimento F
			    break;

			case 31:
			    while (!(matriz[0][0][1].isCor(Cor.LARANJA) && matriz[4][2][1].isCor(Cor.BRANCO)))
			    {
				rotacao.U(cubo);// movimento U
			    }

			    // realizar movimento F2
			    rotacao.F(cubo);// movimento F
			    rotacao.F(cubo);// movimento F
		    }
		    rotacao.Y(cubo);// movimento Y
		}
	    }
	    setDestino(matriz[0][1][1]);

	    while (!matriz[0][1][1].isCor(Cor.AZUL))
	    {
		rotacao.Y(cubo);
	    }

	    if ((matriz[0][2][1].isCor(Cor.AZUL) && matriz[0][1][1].isCor(Cor.AZUL)
		    && matriz[5][0][1].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO))
		    && (matriz[1][2][1].isCor(Cor.VERMELHO) && matriz[1][1][1].isCor(Cor.VERMELHO)
			    && matriz[5][1][2].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO))
		    && (matriz[2][2][1].isCor(Cor.VERDE) && matriz[2][1][1].isCor(Cor.VERDE)
			    && matriz[5][2][1].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO))
		    && (matriz[3][2][1].isCor(Cor.LARANJA) && matriz[3][1][1].isCor(Cor.LARANJA)
			    && matriz[5][1][0].isCor(Cor.BRANCO) && matriz[5][1][1].isCor(Cor.BRANCO)))
	    {

		flag = 1;
	    }

	}
	return;
    }

    /**
     * Método que retorna os movimentos necessários para resolução da etapa Canto Inferior do
     * Cubo à partir de uma configuração recebida juntamente com a explicação necessária
     */

    public void resolveCantoInferior()
    {
	resolveCruz();
	Adesivo[][][] matriz = cubo.getCubo();
	int flag = 0;
	int j = 0;
	if (matriz[5][0][0].getKey() == 45 && matriz[5][0][2].getKey() == 47 && matriz[5][2][0].getKey() == 51
		&& matriz[5][2][2].getKey() == 53)
	    flag = 1;

	while (flag != 1)
	{

	    // etapa1

	    if (matriz[0][0][0].isCor(Cor.BRANCO) | // (matriz[0][0][0].getKey() >= 45 && matriz[0][0][0].getKey() <=
						    // 53) |
		    (matriz[1][0][0].isCor(Cor.BRANCO)) | // matriz[1][0][0].getKey() >= 45 && matriz[1][0][0].getKey()
							  // <= 53) |
		    (matriz[2][0][0].isCor(Cor.BRANCO)) | // [2][0][0].getKey() >= 45 && matriz[2][0][0].getKey() <= 53)
							  // |
		    (matriz[3][0][0].isCor(Cor.BRANCO)))
	    { // matriz[3][0][0].getKey() >= 45 && matriz[3][0][0].getKey() <= 53) ){

		setDestino(matriz[1][0][0]);

		while (!matriz[1][0][0].isCor(Cor.BRANCO))
		{// matriz[1][0][0].getKey() < 45){//enquanto não existir quadrado brano na posi��o [1][0][0]
		    rotacao.U(cubo);
		}

		setDestino(matriz[0][0][2]);

		if (matriz[0][0][2].isCor(Cor.AZUL))
		{// matriz[0][0][2].getKey() >= 0 && matriz[0][0][2].getKey() <= 8){

		    setDestino(matriz[0][1][1]);

		    while (!matriz[0][1][1].isCor(Cor.AZUL))
		    {// matriz[0][1][1].getKey() != 4){//enquanto não existir peça azul
			rotacao.E(cubo);
			rotacao.D(cubo);
		    }
		    setDestino(matriz[0][2][2]);

		    rotacao.R(cubo);
		    rotacao.U(cubo);
		    rotacao.R_(cubo);
		}
		else if (matriz[0][0][2].isCor(Cor.VERMELHO))
		{// matriz[0][0][2].getKey() >= 9 && matriz[0][0][2].getKey() <= 17){

		    setDestino(matriz[0][1][1]);

		    while (!matriz[0][1][1].isCor(Cor.VERMELHO))
		    {// matriz[0][1][1].getKey() != 13){ enquanto não for vermelho
			rotacao.E(cubo);
			rotacao.D(cubo);
		    }
		    setDestino(matriz[0][2][2]);

		    rotacao.R(cubo);
		    rotacao.U(cubo);
		    rotacao.R_(cubo);
		}

		else if (matriz[0][0][2].isCor(Cor.VERDE))
		{// matriz[0][0][2].getKey() >= 18 && matriz[0][0][2].getKey() <= 26){

		    setDestino(matriz[0][1][1]);

		    while (!matriz[0][1][1].isCor(Cor.VERDE))
		    {// matriz[0][1][1].getKey() != 22){ enquanto não for verde
			rotacao.E(cubo);
			rotacao.D(cubo);
		    }
		    setDestino(matriz[0][2][2]);

		    rotacao.R(cubo);
		    rotacao.U(cubo);
		    rotacao.R_(cubo);
		}

		else if (matriz[0][0][2].isCor(Cor.LARANJA))
		{// matriz[0][0][2].getKey() >= 27 && matriz[0][0][2].getKey() <= 35 ){
		    setDestino(matriz[0][1][1]);

		    while (!matriz[0][1][1].isCor(Cor.LARANJA))
		    {// matriz[0][1][1].getKey() != 31){ enquanto não for laranja
			rotacao.E(cubo);
			rotacao.D(cubo);
		    }

		    setDestino(matriz[0][2][2]);

		    rotacao.R(cubo);
		    rotacao.U(cubo);
		    rotacao.R_(cubo);
		}

	    }
	    // fim da etapa 1
	    // **************
	    // etapa 2
	    else if (matriz[0][0][2].isCor(Cor.BRANCO) | // (matriz[0][0][2].getKey() >= 45 && matriz[0][0][2].getKey()
							 // <= 53) |
		    (matriz[1][0][2].isCor(Cor.BRANCO)) | // matriz[1][0][2].getKey() >= 45 && matriz[1][0][2].getKey()
							  // <= 53) |
		    (matriz[2][0][2].isCor(Cor.BRANCO)) | // matriz[2][0][2].getKey() >= 45 && matriz[2][0][2].getKey()
							  // <= 53) |
		    (matriz[3][0][2].isCor(Cor.BRANCO)))
	    {// matriz[3][0][2].getKey() >= 45 && matriz[3][0][2].getKey() <= 53) ){
		setDestino(matriz[3][0][2]);

		while (!matriz[3][0][2].isCor(Cor.BRANCO))
		{// matriz[3][0][2].getKey() < 45){enquanto não for branca
		    rotacao.U(cubo);
		}

		setDestino(matriz[0][0][0]);
		if (matriz[0][0][0].isCor(Cor.AZUL))
		{// matriz[0][0][0].getKey() >= 0 && matriz[0][0][0].getKey() <= 8){
		    setDestino(matriz[0][1][1]);

		    while (!matriz[0][1][1].isCor(Cor.AZUL))
		    {// matriz[0][1][1].getKey() != 4){ enquanto não for azul
			rotacao.E(cubo);
			rotacao.D(cubo);
		    }

		    setDestino(matriz[0][2][0]);

		    rotacao.L_(cubo);
		    rotacao.U_(cubo);
		    rotacao.L(cubo);
		}
		else if (matriz[0][0][0].isCor(Cor.VERMELHO))
		{// matriz[0][0][0].getKey() >= 9 && matriz[0][0][0].getKey() <= 17){
		    setDestino(matriz[0][1][1]);

		    while (!matriz[0][1][1].isCor(Cor.VERMELHO))
		    {// matriz[0][1][1].getKey() != 13){ //enquanto não for vermelho
			rotacao.E(cubo);
			rotacao.D(cubo);
		    }
		    setDestino(matriz[0][2][0]);

		    rotacao.L_(cubo);
		    rotacao.U_(cubo);
		    rotacao.L(cubo);
		}

		else if (matriz[0][0][0].isCor(Cor.VERDE))
		{// matriz[0][0][0].getKey() >= 18 && matriz[0][0][0].getKey() <= 26){
		    setDestino(matriz[0][1][1]);

		    while (!matriz[0][1][1].isCor(Cor.VERDE))
		    {// matriz[0][1][1].getKey() != 22){ //
			rotacao.E(cubo);
			rotacao.D(cubo);
		    }
		    setDestino(matriz[0][2][0]);

		    rotacao.L_(cubo);
		    rotacao.U_(cubo);
		    rotacao.L(cubo);
		}

		else if (matriz[0][0][0].isCor(Cor.LARANJA))
		{// matriz[0][0][0].getKey() >= 27 && matriz[0][0][0].getKey() <= 35){
		    setDestino(matriz[0][1][1]);

		    while (!matriz[0][1][1].isCor(Cor.LARANJA))
		    {// matriz[0][1][1].getKey() != 31){ // enquanto não for laranja
			rotacao.E(cubo);
			rotacao.D(cubo);
		    }
		    setDestino(matriz[0][2][0]);

		    rotacao.L_(cubo);
		    rotacao.U_(cubo);
		    rotacao.L(cubo);
		}

	    }

	    // fim da etapa 2
	    // *****************
	    // etapa 3

	    else if (matriz[4][0][0].isCor(Cor.BRANCO) | // (matriz[4][0][0].getKey() >= 45 && matriz[4][0][0].getKey()
							 // <= 53) ||
		    matriz[4][0][2].isCor(Cor.BRANCO) | // (matriz[4][0][2].getKey() >= 45 && matriz[4][0][2].getKey()
							// <= 53) ||
		    matriz[4][2][0].isCor(Cor.BRANCO) | // (matriz[4][2][0].getKey() >= 45 && matriz[4][2][0].getKey()
							// <= 53) ||
		    matriz[4][2][2].isCor(Cor.BRANCO))
	    {// (matriz[4][2][2].getKey() >= 45 && matriz[4][2][2].getKey() <= 53) ){
		setDestino(matriz[4][2][2]);

		while (!matriz[4][2][2].isCor(Cor.BRANCO))
		{// matriz[4][2][2].getKey() < 45){//enquanto não existir quadrado branco na posi��o [4][2][2]
		    rotacao.U(cubo);
		}

		if (matriz[5][0][2].isCor(Cor.BRANCO))
		{// matriz[5][0][2].getKey() >= 45 && matriz[5][0][2].getKey() <= 53){
		    setDestino(matriz[5][0][2]);

		    while (matriz[5][0][2].isCor(Cor.BRANCO))
		    {// matriz[5][0][2].getKey() >= 45 && matriz[5][0][2].getKey() <= 53){//enquanto existir quadrado
		     // branco na posi��o [5][0][2]
			rotacao.E(cubo);
			rotacao.D(cubo);
		    }
		}

		setDestino(matriz[0][0][0]);

		rotacao.R(cubo);
		rotacao.U(cubo);
		rotacao.U(cubo);
		rotacao.R_(cubo);
	    }
	    // fim da etapa 3
	    // **************
	    // etapa 4
	    else if (matriz[0][2][2].isCor(Cor.BRANCO) | // (matriz[0][2][2].getKey() >= 45 && matriz[0][2][2].getKey()
							 // <= 53) ||
		    matriz[1][2][2].isCor(Cor.BRANCO) | // (matriz[1][2][2].getKey() >= 45 && matriz[1][2][2].getKey()
							// <= 53) ||
		    matriz[2][2][2].isCor(Cor.BRANCO) | // (matriz[2][2][2].getKey() >= 45 && matriz[2][2][2].getKey()
							// <= 53) ||
		    matriz[3][2][2].isCor(Cor.BRANCO))
	    {// (matriz[3][2][2].getKey() >= 45 && matriz[3][2][2].getKey() <= 53) ){
		setDestino(matriz[0][2][2]);

		while (!matriz[0][2][2].isCor(Cor.BRANCO))
		{// matriz[0][2][2].getKey() < 45){//enquanto não existir quadrado branco na posi��o [0][2][2]
		    rotacao.Y(cubo);
		}
		setDestino(matriz[0][2][2]);

		rotacao.R(cubo);
		rotacao.U_(cubo);
		rotacao.R_(cubo);
	    }

	    // fim da etapa 4
	    // **************
	    // etapa 5
	    else if (matriz[0][2][0].isCor(Cor.BRANCO) | // (matriz[0][2][0].getKey() >= 45 && matriz[0][2][0].getKey()
							 // <= 53) ||
		    matriz[1][2][0].isCor(Cor.BRANCO) | // (matriz[1][2][0].getKey() >= 45 && matriz[1][2][0].getKey()
							// <= 53) ||
		    matriz[2][2][0].isCor(Cor.BRANCO) | // (matriz[2][2][0].getKey() >= 45 && matriz[2][2][0].getKey()
							// <= 53) ||
		    matriz[3][2][0].isCor(Cor.BRANCO))
	    {// (matriz[3][2][0].getKey() >= 45 && matriz[3][2][0].getKey() <= 53) ){
		setDestino(matriz[0][2][0]);

		while (!matriz[0][2][0].isCor(Cor.BRANCO))
		{// matriz[0][2][0].getKey() < 45){//enquanto não existir quadrado branco na posi��o [0][2][0]
		    rotacao.Y(cubo);
		}

		setDestino(matriz[0][2][0]);

		rotacao.L_(cubo);
		rotacao.U(cubo);
		rotacao.L(cubo);
	    }
	    // fim da etapa 5
	    // *****************
	    // etapa 6
	    else
	    {
		setDestino(matriz[0][2][0]);
		for (int i = 0; i < 4; i++)
		{
		    setDestino(matriz[1][0][0]);
		    if (matriz[0][2][0].isCor(Cor.AZUL))
		    {// matriz[0][2][0].getKey() <= 8){
			if (!matriz[0][1][1].isCor(Cor.AZUL))
			{// matriz[0][1][1].getKey() != 4){
			    rotacao.L_(cubo);
			    rotacao.U_(cubo);
			    rotacao.L(cubo);
			}
		    }
		    else if (matriz[0][2][0].isCor(Cor.VERMELHO))
		    {// matriz[0][2][0].getKey() >= 9 && matriz[0][2][0].getKey() <= 17){
			if (!matriz[0][1][1].isCor(Cor.VERMELHO))
			{// matriz[0][1][1].getKey() != 13){
			    rotacao.L_(cubo);
			    rotacao.U_(cubo);
			    rotacao.L(cubo);
			}
		    }
		    else if (matriz[0][2][0].isCor(Cor.VERDE))
		    {// matriz[0][2][0].getKey() >= 18 && matriz[0][2][0].getKey() <= 26){
			if (!matriz[0][1][1].isCor(Cor.VERDE))
			{// matriz[0][1][1].getKey() != 22){
			    rotacao.L_(cubo);
			    rotacao.U_(cubo);
			    rotacao.L(cubo);
			}
		    }
		    else if (matriz[0][2][0].isCor(Cor.LARANJA))
		    {// matriz[0][2][0].getKey() >= 27 && matriz[0][2][0].getKey() <= 35){
			if (!matriz[0][1][1].isCor(Cor.LARANJA))
			{// matriz[0][1][1].getKey() != 31){
			    rotacao.L_(cubo);
			    rotacao.U_(cubo);
			    rotacao.L(cubo);
			}
		    }
		    rotacao.Y(cubo);
		}

	    }
	    // fim da etapa 6
	    if (matriz[5][0][0].isCor(Cor.BRANCO) && // matriz[5][0][0].getKey() >= 45 &&
		    matriz[5][0][2].isCor(Cor.BRANCO) && // matriz[5][0][2].getKey() >= 45 &&
		    matriz[5][2][0].isCor(Cor.BRANCO) && // matriz[5][2][0].getKey() >= 45 &&
		    matriz[5][2][2].isCor(Cor.BRANCO))// matriz[5][2][2].getKey() >= 45)
		flag = 1;
	}
	return;
    }

    /**
     * Método que retorna os movimentos necessários para resolução da etapa Camada do Meio do
     * Cubo a partir de uma configuração recebida juntamente com a explicação necessária
     */
    public void resolveCamadaMeio()
    {
	resolveCantoInferior();

	int flag = 1, k = 0;
	int cont = 0;
	int flag2 = 0;
	int flag3 = 0;
	Adesivo[][][] matriz = cubo.getCubo();
	int x = 0;

	// TESTE PARA VER SE A CAMADA 2 está PRONTA
	while (flag != 0)
	{

	    flag = 0;
	    if (/* matriz[0][1][1].isCor(Cor.AZUL) */matriz[0][1][1].getKey() == 4)
	    { // teste quando a face AZUL está para frente
		k = 3;
		for (int i = 0; i < 4; i = i + 2)
		{
		    if ((matriz[i][1][0].getKey() != k) || (matriz[i][1][2].getKey() != k + 2))
		    {
			flag = 1;
		    }
		    k = k + 18;
		}
	    }

	    if (matriz[0][1][1].getKey() == 13)
	    { // teste quando a face VERMELHA está para frente
		k = 12;
		for (int i = 0; i < 4; i = i + 2)
		{
		    if ((matriz[i][1][0].getKey() != k) || (matriz[i][1][2].getKey() != k + 2))
		    {
			flag = 1;
		    }
		    k = k + 18;
		}
	    }

	    if (matriz[0][1][1].getKey() == 22)
	    { // teste quando a face VERDE está para frente
		k = 21;
		for (int i = 0; i < 4; i = i + 2)
		{
		    if ((matriz[i][1][0].getKey() != k) || (matriz[i][1][2].getKey() != k + 2))
		    {
			flag = 1;
		    }
		    k = k - 18;
		}
	    }

	    if (matriz[0][1][1].getKey() == 31)
	    { // teste quando a face LARANJA está para frente
		k = 30;
		for (int i = 0; i < 4; i = i + 2)
		{
		    if ((matriz[i][1][0].getKey() != k) || (matriz[i][1][2].getKey() != k + 2))
		    {
			flag = 1;
		    }
		    k = k - 18;
		}
	    }
	    // if(flag == 0) camada 2 está pronta
	    // else camada 2 não está pronta

	    // TESTE PARA VER SE TEM AMARELO NOS MEIOS DA CAMADA DE CIMA
	    cont = 0;
	    if (flag == 1)
	    {

		for (int j = 0; j < 4; j++)
		{
		    if (matriz[j][0][1].isCor(Cor.AMARELO)/* matriz[j][0][1].getKey() >= 36 && matriz[j][0][1] <=44 */)
			cont++;
		}
		if (matriz[4][0][1].isCor(Cor.AMARELO)/* matriz[4][0][1].getKey() >= 36 && matriz[4][0][1] <=44 */)
		    cont++;
		if (matriz[4][1][0].isCor(Cor.AMARELO)/* matriz[4][1][0].getKey() >= 36 && matriz[4][1][0] <=44 */)
		    cont++;
		if (matriz[4][1][2].isCor(Cor.AMARELO)/* matriz[4][1][2].getKey() >= 36 && matriz[4][1][2] <=44 */)
		    cont++;
		if (matriz[4][2][1].isCor(Cor.AMARELO)/* matriz[4][2][1].getKey() >= 36 && matriz[4][2][1] <=44 */)
		    cont++;

		// if(cont<4) alguma das pe�as do meio nao tem amarelo
		// else todas pe�as do meio possuem amarelo
	    }

	    // FAZENDO A SEGUNDA CAMADA
	    if ((cont < 4) && (flag == 1))
	    {
		flag2 = 0;

		setDestino(matriz[0][0][1]);

		while (matriz[0][0][1].isCor(Cor.AMARELO) || /* enquanto for amarelo *//*
										        * matriz[0][0][1].getKey() >= 36
										        * && matriz[0][0][1] <=44 ||
										        * matriz[4][2][1].getKey() >= 36
										        * && matriz[4][2][1] <=44
										        */
		matriz[4][2][1].isCor(Cor.AMARELO))
		{
		    rotacao.U(cubo);

		}

		setDestino(matriz[0][0][1]);

		if ((/* matriz[0][0][1].isCor(Cor.AZUL) */matriz[0][0][1].getKey() == 3)
			|| (matriz[0][0][1].getKey() == 5))
		{// se for azul

		    if (!(matriz[0][1][1].isCor(Cor.AZUL)/* matriz[0][1][1].getKey() == 4 */))
		    {
			setDestino(matriz[0][1][1]);

			while (!matriz[0][1][1].isCor(Cor.AZUL)/* matriz[0][1][1].getKey() != 4 */)
			{// enquanto não for azul
			    rotacao.D(cubo);
			    rotacao.E(cubo);
			}

		    }
		    if (matriz[0][0][1].getKey() == 3)
			flag2 = 0;
		    else if (matriz[0][0][1].getKey() == 5)
			flag2 = 1;
		}
		else
		{
		    if (/* matriz[0][0][1].isCor(Cor.VERMELHO) */(matriz[0][0][1].getKey() == 12)
			    || (matriz[0][0][1].getKey() == 14))
		    {// se for vermelho
			if (!(/* matriz[0][1][1].isCor(Cor.VERMELHO) */matriz[0][1][1].getKey() == 13))
			{
			    setDestino(matriz[0][1][1]);
			    while (/* !matriz[0][1][1].isCor(Cor.VERDE) */matriz[0][1][1].getKey() != 13)
			    {
				rotacao.D(cubo);
				rotacao.E(cubo);
			    }
			}

			if (matriz[0][0][1].getKey() == 12)
			    flag2 = 0;
			else if (matriz[0][0][1].getKey() == 14)
			    flag2 = 1;
		    }
		    else
		    {
			if (/* matriz[0][0][1].isCor(Cor.VERDE) */(matriz[0][0][1].getKey() == 21)
				|| (matriz[0][0][1].getKey() == 23))
			{
			    if (!(/* matriz[0][1][1].isCor(Cor.VERDE) */matriz[0][1][1].getKey() == 22))
			    {
				setDestino(matriz[0][1][1]);
				while (/* !matriz[0][1][1].isCor(Cor.VERDE) */matriz[0][1][1].getKey() != 22)
				{
				    rotacao.D(cubo);
				    rotacao.E(cubo);
				}
			    }
			    if (matriz[0][0][1].getKey() == 21)
				flag2 = 0;
			    else if (matriz[0][0][1].getKey() == 23)
				flag2 = 1;
			}
			else
			{
			    if (/* matriz[0][0][1].isCor(Cor.LARANJA) */(matriz[0][0][1].getKey() == 30)
				    || (matriz[0][0][1].getKey() == 32))
			    {
				if (!(matriz[0][1][1].isCor(Cor.LARANJA)/* matriz[0][1][1].getKey() == 31 */))
				{
				    setDestino(matriz[0][1][1]);
				    while (/* !matriz[0][1][1].isCor(Cor.LARANJA) */matriz[0][1][1].getKey() != 31)
				    {
					rotacao.D(cubo);
					rotacao.E(cubo);
				    }
				}
				if (matriz[0][0][1].getKey() == 30)
				    flag2 = 0;
				else if (matriz[0][0][1].getKey() == 32)
				    flag2 = 1;
			    }
			}
		    }
		}
		setDestino(matriz[4][2][1]);

		if (flag2 == 0)
		{
		    setDestino(matriz[1][1][1]);
		    rotacao.U_(cubo);
		    rotacao.L_(cubo);
		    rotacao.U_(cubo);
		    rotacao.L(cubo);
		    rotacao.U(cubo);
		    rotacao.Y_(cubo);
		    rotacao.R(cubo);
		    rotacao.U(cubo);
		    rotacao.R_(cubo);
		}
		else
		{
		    if (flag2 == 1)
		    {
			setDestino(matriz[3][1][1]);
			rotacao.U(cubo);
			rotacao.R(cubo);
			rotacao.U(cubo);
			rotacao.R_(cubo);
			rotacao.U_(cubo);
			rotacao.Y(cubo);
			rotacao.L_(cubo);
			rotacao.U_(cubo);
			rotacao.L(cubo);
		    }
		}
	    }
	    else
	    {
		// flag3=0;
		if ((cont == 4) && (flag == 1))
		{
		    flag3 = 0;
		    if (matriz[0][1][1].isCor(Cor.AZUL)/* matriz[0][1][1].getKey() == 4 */)
		    { // verificando pecas erradas na face azul
			k = 3;
			setOrigem(matriz[0][1][1]);

			for (int i = 0; i < 4; i = i + 2)
			{
			    if ((matriz[i][1][0].getKey() != k) || (matriz[i][1][2].getKey() != k + 2))
			    {

				if (matriz[i][1][0].getKey() != k && i == 0)
				    flag3 = 1;
				else if (matriz[i][1][2].getKey() != k + 2 && i == 0)
				    flag3 = 0;
				else if (matriz[i][1][0].getKey() != k && i == 2)
				{
				    flag3 = 1;

				    setOrigem(matriz[i][1][0]);

				    rotacao.Y(cubo);
				    rotacao.Y(cubo);
				}
				else if (matriz[i][1][2].getKey() != k + 2 && i == 2)
				{
				    flag3 = 0;

				    setOrigem(matriz[i][1][0]);

				    rotacao.Y(cubo);
				    rotacao.Y(cubo);
				}
			    }
			    k = k + 18;
			}
		    }

		    if (matriz[0][1][1].isCor(Cor.VERMELHO)/* matriz[0][1][1].getKey() == 13 */)
		    { // verificando pecas erradas na face vermelha
			k = 12;
			setOrigem(matriz[0][1][1]);

			for (int i = 0; i < 4; i = i + 2)
			{
			    if ((matriz[i][1][0].getKey() != k) || (matriz[i][1][2].getKey() != k + 2))
			    {
				if (matriz[i][1][0].getKey() != k && i == 0)
				    flag3 = 1;
				else if (matriz[i][1][2].getKey() != k + 2 && i == 0)
				    flag3 = 0;
				else if (matriz[i][1][0].getKey() != k && i == 2)
				{
				    flag3 = 1;

				    setOrigem(matriz[i][1][0]);

				    rotacao.Y(cubo);
				    rotacao.Y(cubo);
				}
				else if (matriz[i][1][2].getKey() != k + 2 && i == 2)
				{
				    flag3 = 0;

				    setOrigem(matriz[i][1][0]);

				    rotacao.Y(cubo);
				    rotacao.Y(cubo);
				}
			    }
			    k = k + 18;
			}
		    }

		    if (matriz[0][1][1].isCor(Cor.VERDE)/* matriz[0][1][1].getKey() == 22 */)
		    { // verificando pecas erradas na face verde
			k = 21;
			setOrigem(matriz[0][1][1]);
			for (int i = 0; i < 4; i = i + 2)
			{
			    if ((matriz[i][1][0].getKey() != k) || (matriz[i][1][2].getKey() != k + 2))
			    {
				if (matriz[i][1][0].getKey() != k && i == 0)
				    flag3 = 1;
				else if (matriz[i][1][2].getKey() != k + 2 && i == 0)
				    flag3 = 0;
				else if (matriz[i][1][0].getKey() != k && i == 2)
				{
				    flag3 = 1;

				    setOrigem(matriz[i][1][0]);

				    rotacao.Y(cubo);
				    rotacao.Y(cubo);
				}
				else if (matriz[i][1][2].getKey() != k + 2 && i == 2)
				{
				    flag3 = 0;

				    setOrigem(matriz[i][1][0]);

				    rotacao.Y(cubo);
				    rotacao.Y(cubo);
				}
			    }
			    k = k - 18;
			}
		    }

		    if (matriz[0][1][1].getKey() == 31)
		    { // verificando pecas erradas na face laranja
			k = 30;
			setOrigem(matriz[0][1][1]);
			for (int i = 0; i < 4; i = i + 2)
			{
			    if ((matriz[i][1][0].getKey() != k) || (matriz[i][1][2].getKey() != k + 2))
			    {
				if (matriz[i][1][0].getKey() != k && i == 0)
				    flag3 = 1;
				else if (matriz[i][1][2].getKey() != k + 2 && i == 0)
				    flag3 = 0;
				else if (matriz[i][1][0].getKey() != k && i == 2)
				{
				    flag3 = 1;
				    setOrigem(matriz[i][1][0]);

				    rotacao.Y(cubo);
				    rotacao.Y(cubo);
				}
				else if (matriz[i][1][2].getKey() != k + 2 && i == 2)
				{
				    flag3 = 0;

				    setOrigem(matriz[i][1][0]);

				    rotacao.Y(cubo);
				    rotacao.Y(cubo);
				}
			    }
			    k = k - 18;
			}
		    }

		    if (flag3 == 1)
		    {
			rotacao.L_(cubo);
			rotacao.U_(cubo);
			rotacao.L(cubo);
			rotacao.U(cubo);
			rotacao.Y_(cubo);
			rotacao.R(cubo);
			rotacao.U(cubo);
			rotacao.R_(cubo);
		    }
		    else if (flag3 == 0)
		    {

			rotacao.R(cubo);
			rotacao.U(cubo);
			rotacao.R_(cubo);
			rotacao.U_(cubo);
			rotacao.Y(cubo);
			rotacao.L_(cubo);
			rotacao.U_(cubo);
			rotacao.L(cubo);
		    }

		}
	    }
	}
	return;
    }

    /**
     * Método que retorna os movimentos necessários para resolução da etapa Cruz Superior do
     * Cubo à partir de uma configuração recebida juntamente com a explicação necessária
     */
    public void resolveCruzSuperior()
    {
	resolveCamadaMeio();
	Adesivo[][][] matriz = cubo.getCubo();
	int flag = 0;
	int contAmarelo = 0;
	int x = 0;
	if (matriz[4][0][1].isCor(Cor.AMARELO)/* matriz[4][0][1].getKey() >= 36 && matriz[4][0][1].getKey() <= 44 */)
	    contAmarelo++;

	if (matriz[4][1][0].getKey() >= 36 && matriz[4][1][0].getKey() <= 44)
	    contAmarelo++;

	if (matriz[4][1][2].getKey() >= 36 && matriz[4][1][2].getKey() <= 44)
	    contAmarelo++;

	if (matriz[4][2][1].getKey() >= 36 && matriz[4][2][1].getKey() <= 44)
	    contAmarelo++;
	setOrigem(matriz[4][0][1]);
	setDestino(matriz[4][1][0]);
	setOrigemDois(matriz[4][1][2]);
	setDestinoDois(matriz[4][2][1]);

	if (contAmarelo == 4)
	{
	    return;
	    // /flag = 1;
	}

	// /while(flag != 1){
	// etapa 1
	if (contAmarelo == 0)
	{
	    setOrigem(matriz[4][0][1]);
	    setDestino(matriz[4][2][1]);

	    rotacao.F(cubo);
	    rotacao.U(cubo);
	    rotacao.R(cubo);
	    rotacao.U_(cubo);
	    rotacao.R_(cubo);
	    rotacao.F_(cubo);

	    rotacao.U(cubo);
	    setOrigem(matriz[4][0][1]);
	    setDestino(matriz[4][1][0]);

	    rotacao.F(cubo);
	    rotacao.U(cubo);
	    rotacao.R(cubo);
	    rotacao.U_(cubo);
	    rotacao.R_(cubo);
	    rotacao.F_(cubo);

	    setOrigem(matriz[4][1][2]);
	    setDestino(matriz[4][2][1]);

	    rotacao.F(cubo);
	    rotacao.U(cubo);
	    rotacao.R(cubo);
	    rotacao.U_(cubo);
	    rotacao.R_(cubo);
	    rotacao.F_(cubo);
	}
	else
	{
	    while (!((matriz[4][1][0].getKey() >= 36 && matriz[4][1][0].getKey() <= 44 && // enquanto não for amarelo
		    matriz[4][0][1].getKey() >= 36 && matriz[4][0][1].getKey() <= 44) ||

	    (matriz[4][1][0].getKey() >= 36 && matriz[4][1][0].getKey() <= 44 && matriz[4][1][2].getKey() >= 36 && matriz[4][1][2]
		    .getKey() <= 44)))
	    {

		rotacao.U(cubo);
	    }
	    if (matriz[4][0][1].getKey() >= 36 && matriz[4][0][1].getKey() <= 44)
	    {
		setOrigem(matriz[4][0][1]);
		setDestino(matriz[4][1][0]);

		rotacao.F(cubo);
		rotacao.U(cubo);
		rotacao.R(cubo);
		rotacao.U_(cubo);
		rotacao.R_(cubo);
		rotacao.F_(cubo);
	    }

	    else
	    {
		setOrigem(matriz[4][1][2]);
		setDestino(matriz[4][1][0]);

		rotacao.F(cubo);
		rotacao.U(cubo);
		rotacao.R(cubo);
		rotacao.U_(cubo);
		rotacao.R_(cubo);
		rotacao.F_(cubo);
		rotacao.F(cubo);
		rotacao.U(cubo);
		rotacao.R(cubo);
		rotacao.U_(cubo);
		rotacao.R_(cubo);
		rotacao.F_(cubo);
	    }
	}

	contAmarelo = 0;

	if (matriz[4][0][1].getKey() >= 36 && matriz[4][0][1].getKey() <= 44)
	    contAmarelo++;

	if (matriz[4][1][0].getKey() >= 36 && matriz[4][1][0].getKey() <= 44)
	    contAmarelo++;

	if (matriz[4][1][2].getKey() >= 36 && matriz[4][1][2].getKey() <= 44)
	    contAmarelo++;

	if (matriz[4][2][1].getKey() >= 36 && matriz[4][2][1].getKey() <= 44)
	    contAmarelo++;

	if (contAmarelo == 4)
	    flag = 1;

	// }
	// cubo.executaSequencia(movs);
	// for (Iterator iter = movs.iterator(); iter.hasNext();) {
	// Integer element = (Integer) iter.next();
	// MovimentoCuboModel.passo(element.intValue());
	// }
	return;
    }

    /**
     * Método que retorna os movimentos necessários para resolução da etapa Face Amarela do
     * Cubo à partir de uma configuração recebida juntamente com a explicação necessária
     */

    public void resolveFaceAmarela()
    {
	resolveCruzSuperior();

	Adesivo[][][] matriz = cubo.getCubo();
	int flag = 0;
	int contAmarelo = 0;
	int x = 0;

	if (matriz[4][0][0].getKey() >= 36 && matriz[4][0][0].getKey() <= 44)
	    contAmarelo++;

	if (matriz[4][0][2].getKey() >= 36 && matriz[4][0][2].getKey() <= 44)
	    contAmarelo++;

	if (matriz[4][2][0].getKey() >= 36 && matriz[4][2][0].getKey() <= 44)
	    contAmarelo++;

	if (matriz[4][2][2].getKey() >= 36 && matriz[4][2][2].getKey() <= 44)
	    contAmarelo++;

	if (contAmarelo == 4)
	    flag = 1;

	while (flag == 0)
	{

	    setDestino(matriz[3][0][2]);

	    // etapa 1
	    if (contAmarelo == 0)
	    {

		while (!matriz[3][0][2].isCor(Cor.AMARELO)/*
							   * matriz[3][0][2].getKey() < 36 || matriz[3][0][2].getKey() >
							   * 44
							   */)
		{// enqunto não for amarelo
		    rotacao.U(cubo);
		}
		setOrigem(matriz[4][2][2]);
		setDestino(matriz[4][0][0]);

		rotacao.R(cubo);
		rotacao.U(cubo);
		rotacao.R_(cubo);
		rotacao.U(cubo);
		rotacao.R(cubo);
		rotacao.U(cubo);
		rotacao.U(cubo);
		rotacao.R_(cubo);
	    }

	    else if (contAmarelo == 2)
	    {
		setDestino(matriz[0][0][0]);

		while (matriz[0][0][0].getKey() < 36 || matriz[0][0][0].getKey() > 44)
		{
		    // face amarela while 3
		    rotacao.U(cubo);
		}
		rotacao.R(cubo);
		rotacao.U(cubo);
		rotacao.R_(cubo);
		rotacao.U(cubo);
		rotacao.R(cubo);
		rotacao.U(cubo);
		rotacao.U(cubo);
		rotacao.R_(cubo);
	    }
	    else
	    {
		setDestino(matriz[4][2][0]);

		while (matriz[4][2][0].getKey() < 36 || matriz[4][2][0].getKey() > 44)
		{
		    rotacao.U(cubo);
		}

		rotacao.R(cubo);
		rotacao.U(cubo);
		rotacao.R_(cubo);
		rotacao.U(cubo);
		rotacao.R(cubo);
		rotacao.U(cubo);
		rotacao.U(cubo);
		rotacao.R_(cubo);
	    }
	    contAmarelo = 0;

	    if (matriz[4][0][0].getKey() >= 36 && matriz[4][0][0].getKey() <= 44)
		contAmarelo++;

	    if (matriz[4][0][2].getKey() >= 36 && matriz[4][0][2].getKey() <= 44)
		contAmarelo++;

	    if (matriz[4][2][0].getKey() >= 36 && matriz[4][2][0].getKey() <= 44)
		contAmarelo++;

	    if (matriz[4][2][2].getKey() >= 36 && matriz[4][2][2].getKey() <= 44)
		contAmarelo++;

	    if (contAmarelo == 4)
		flag = 1;
	}
	return;
    }

    /**
     * Método que retorna os movimentos necessários para resolução da etapa Canto Superior do
     * Cubo à partir de uma configuração recebida juntamente com a explicação necessária
     */
    public void resolveCantoSuperior()
    {
	resolveFaceAmarela();

	Adesivo[][][] matriz = cubo.getCubo();
	int flag = 0;
	int x = 0;

	if ((matriz[0][0][0].getCor()).equals(matriz[0][0][2].getCor())
		& (matriz[1][0][0].getCor()).equals(matriz[1][0][2].getCor())
		& (matriz[2][0][0].getCor()).equals(matriz[2][0][2].getCor())
		& (matriz[3][0][0].getCor()).equals(matriz[3][0][2].getCor()))
	{
	    flag = 1;
	}

	while (flag != 1)
	{
	    // etapa 2 e 3
	    if ((matriz[0][0][0].getCor()).equals(matriz[0][0][2].getCor())
		    | (matriz[1][0][0].getCor()).equals(matriz[1][0][2].getCor())
		    | (matriz[2][0][0].getCor()).equals(matriz[2][0][2].getCor())
		    | (matriz[3][0][0].getCor()).equals(matriz[3][0][2].getCor()))
	    {

		setOrigem(matriz[2][0][0]);
		setDestino(matriz[2][0][2]);

		while (!matriz[2][0][0].getCor().equals(matriz[2][0][2].getCor()))
		{
		    rotacao.U(cubo);
		}
		rotacao.R_(cubo);
		rotacao.F(cubo);
		rotacao.R_(cubo);
		rotacao.B(cubo);
		rotacao.B(cubo);
		rotacao.R(cubo);
		rotacao.F_(cubo);
		rotacao.R_(cubo);
		rotacao.B(cubo);
		rotacao.B(cubo);
		rotacao.R(cubo);
		rotacao.R(cubo);
	    }
	    else
	    {
		rotacao.R_(cubo);
		rotacao.F(cubo);
		rotacao.R_(cubo);
		rotacao.B(cubo);
		rotacao.B(cubo);
		rotacao.R(cubo);
		rotacao.F_(cubo);
		rotacao.R_(cubo);
		rotacao.B(cubo);
		rotacao.B(cubo);
		rotacao.R(cubo);
		rotacao.R(cubo);
	    }

	    if ((matriz[0][0][0].getCor()).equals(matriz[0][0][2].getCor())
		    & (matriz[1][0][0].getCor()).equals(matriz[1][0][2].getCor())
		    & (matriz[2][0][0].getCor()).equals(matriz[2][0][2].getCor())
		    & (matriz[3][0][0].getCor()).equals(matriz[3][0][2].getCor()))
	    {
		flag = 1;
	    }
	}
	return;
    }

    /**
     * Método que retorna os movimentos necessários para resolução da etapa Meio Superior do
     * Cubo à partir de uma configuração recebida juntamente com a explicação necessária
     */
    public void resolveMeioSuperior()
    {
	resolveCantoSuperior();
	MainAuxiliar.Gravar(MainAuxiliar.arquivo_passo_anterior, "Cubo antes do último passo:");
	MainAuxiliar.Gravar(MainAuxiliar.arquivo_passo_anterior, cubo);

	Adesivo[][][] matriz = cubo.getCubo();
	int x = 0;
	// int flag = 0;
	while (true)
	{
	    setDestino(matriz[0][0][0]);
	    setDestinoDois(matriz[0][0][2]);
	    setOrigem(matriz[0][1][1]);
	    while (!(matriz[0][0][0].getCor().equals(matriz[0][1][1].getCor())))
	    {
		rotacao.U(cubo);
	    }
	    if (matriz[0][0][0].getCor().equals(matriz[0][0][1].getCor())
		    && matriz[0][0][1].getCor().equals(matriz[0][0][2].getCor())
		    && matriz[1][0][0].getCor().equals(matriz[1][0][1].getCor())
		    && matriz[1][0][1].getCor().equals(matriz[1][0][2].getCor())
		    & matriz[2][0][0].getCor().equals(matriz[2][0][1].getCor())
		    && matriz[2][0][1].getCor().equals(matriz[2][0][2].getCor())
		    & matriz[3][0][0].getCor().equals(matriz[3][0][1].getCor())
		    && matriz[3][0][1].getCor().equals(matriz[3][0][2].getCor()))
	    {
		return;
	    }
	    else if (((matriz[0][0][0].getCor()).equals(matriz[0][0][1].getCor()) & matriz[0][0][1].getCor().equals(
		    matriz[0][0][2].getCor()))
		    | ((matriz[1][0][0].getCor()).equals(matriz[1][0][1].getCor()) & matriz[1][0][1].getCor().equals(
			    matriz[1][0][2].getCor()))
		    | ((matriz[2][0][0].getCor()).equals(matriz[2][0][1].getCor()) & matriz[2][0][1].getCor().equals(
			    matriz[2][0][2].getCor()))
		    | ((matriz[3][0][0].getCor()).equals(matriz[3][0][1].getCor()) & matriz[3][0][1].getCor().equals(
			    matriz[3][0][2].getCor())))
	    {
		setDestino(matriz[0][0][0]);
		setDestinoDois(matriz[0][0][2]);

		setOrigem(matriz[0][1][1]);

		while (!matriz[2][0][0].getCor().equals(matriz[2][0][1].getCor())
			&& !matriz[2][0][1].getCor().equals(matriz[2][0][2].getCor()))
		{
		    rotacao.Y(cubo);
		}

		if (matriz[0][0][1].getCor().equals(matriz[3][1][1].getCor()))
		{
		    setDestino(matriz[0][0][1]);
		    setOrigem(matriz[3][1][1]);

		    rotacao.F(cubo);
		    rotacao.F(cubo);
		    rotacao.U(cubo);
		    rotacao.L(cubo);
		    rotacao.R_(cubo);
		    rotacao.F(cubo);
		    rotacao.F(cubo);
		    rotacao.L_(cubo);
		    rotacao.R(cubo);
		    rotacao.U(cubo);
		    rotacao.F(cubo);
		    rotacao.F(cubo);
		}
		else if (matriz[0][0][1].getCor().equals(matriz[1][1][1].getCor()))
		{

		    rotacao.F(cubo);
		    rotacao.F(cubo);
		    rotacao.U_(cubo);
		    rotacao.L(cubo);
		    rotacao.R_(cubo);
		    rotacao.F(cubo);
		    rotacao.F(cubo);
		    rotacao.L_(cubo);
		    rotacao.R(cubo);
		    rotacao.U_(cubo);
		    rotacao.F(cubo);
		    rotacao.F(cubo);

		    setDestino(matriz[0][0][1]);
		    setOrigem(matriz[3][1][1]);
		}
	    }
	    else
	    {
		rotacao.F(cubo);
		rotacao.F(cubo);
		rotacao.U(cubo);
		rotacao.L(cubo);
		rotacao.R_(cubo);
		rotacao.F(cubo);
		rotacao.F(cubo);
		rotacao.L_(cubo);
		rotacao.R(cubo);
		rotacao.U(cubo);
		rotacao.F(cubo);
		rotacao.F(cubo);
		setDestino(matriz[0][0][1]);
		setOrigem(matriz[1][1][1]);
	    }
	    try
	    {
		Thread.sleep(3000);
	    }
	    catch (InterruptedException e)
	    {
		// TODO Auto-generated catch block
		e.printStackTrace();
	    }
	}
    }

    public void setCubo(CuboMagico3x3x3 cubo)
    {
	this.cubo = cubo;
    }

    public Adesivo getDestino()
    {
	return destino;
    }

    public void setDestino(Adesivo destino)
    {
	this.destino = destino;
    }

    public String getMensagem()
    {
	return mensagem;
    }

    public void setMensagem(String mensagem)
    {
	this.mensagem = mensagem;
    }

    public Adesivo getOrigem()
    {
	return origem;
    }

    public void setOrigem(Adesivo origem)
    {
	this.origem = origem;
    }

    public int getPasso()
    {
	return passo;
    }

    public void setPasso(int passo)
    {
	this.passo = passo;
    }

    public Adesivo getOrigemDois()
    {
	return origemDois;
    }

    public void setOrigemDois(Adesivo origemDois)
    {
	this.origemDois = origemDois;
    }

    public Adesivo getDestinoDois()
    {
	return destinoDois;
    }

    public void setDestinoDois(Adesivo destinoDois)
    {
	this.destinoDois = destinoDois;
    }

}